{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n\n# microTVM Reference Virtual Machines\n\n**Author**: `Andrew Reusch <areusch@octoml.ai>`_\n\nThis tutorial explains how to launch microTVM Reference Virtual Machines. You can use these to\ndevelop on real physical hardware without needing to individually install the microTVM\ndependencies. These are also particularly useful when trying to reproduce behavior with\nmicroTVM, such as when filing bug reports.\n\nmicroTVM is the effort to allow TVM to build and execute models on bare-metal microcontrollers.\nmicroTVM aims to be compatible with a wide variety of SoCs and runtime environments (i.e. bare metal,\nRTOS, etc). However, some stable software environment is needed to allow developers to share and\nreproduce bugs and results. The microTVM Reference Virtual Machines are intended to provide that\nenvironment.\n\nHow it works\n============\n\nNo Virtual Machines are stored in the TVM repository--instead, the files stored in\n``apps/microtvm/reference-vm`` describe how to build VMs to the Vagrant_ VM builder tool.\n\nThe Reference VMs are split into two parts:\n\n1. A Vagrant Base Box, which contains all of the stable dependencies for that platform. Build\n   scripts are stored in ``apps/microtvm/reference-vm/<platform>/base-box``. TVM committers run\n   these when a platform's \"stable\" dependencies change, and the generated base boxes are stored in\n   `Vagrant Cloud`_.\n2. A per-workspace VM, which users normally build using the Base Box as a starting point. Build\n   scripts are stored in ``apps/microtvm/reference-vm/<platform>`` (everything except ``base-box``).\n\n\nSetting up the VM\n=================\n\nInstalling prerequisites\n------------------------\n\nA minimal set of prerequisites are needed:\n\n1. `Vagrant <https://vagrantup.com>`__\n2. A supported Virtual Machine hypervisor (**VirtualBox**, **Parallels**, or **VMWare Fusion/Workstation**).\n   `VirtualBox <https://www.virtualbox.org>`__ is a suggested free hypervisor, but please note\n   that the `VirtualBox Extension Pack`_ is required for proper USB forwarding. If using VirtualBox,\n   also consider installing the `vbguest <https://github.com/dotless-de/vagrant-vbguest>`_ plugin.\n\n\n3. If required for your hypervisor, the\n   `Vagrant provider plugin <https://github.com/hashicorp/vagrant/wiki/Available-Vagrant-Plugins#providers>`__ (or see `here <https://www.vagrantup.com/vmware>`__ for VMWare).\n\nFirst boot\n----------\n\nThe first time you use a reference VM, you need to create the box locally and then provision it.\n\n.. code-block:: bash\n\n    # Replace zephyr with the name of a different platform, if you are not using Zephyr.\n    ~/.../tvm $ cd apps/microtvm/reference-vm/zephyr\n    # Replace <provider_name> with the name of the hypervisor you wish to use (i.e. virtualbox, parallels, vmware_desktop).\n    ~/.../tvm/apps/microtvm/reference-vm/zephyr $ vagrant up --provider=<provider_name>\n\n\nThis command will take a couple of minutes to run and will require 4 to 5GB of storage on your\nmachine. It does the following:\n\n1. Downloads the `microTVM base box`_ and clones it to form a new VM specific to this TVM directory.\n2. Mounts your TVM directory (and, if using ``git-subtree``, the original ``.git`` repo) into the\n   VM.\n3. Builds TVM and installs a Python virtualenv with the dependencies corresponding with your TVM\n   build.\n\n\nConnect Hardware to the VM\n--------------------------\n\nNext, you need to configure USB passthrough to attach your physical development board to the virtual\nmachine (rather than directly to your laptop's host OS).\n\nIt's suggested you setup a device filter, rather than doing a one-time forward, because often the\ndevice may reboot during the programming process and you may, at that time, need to enable\nforwarding again. It may not be obvious to the end user when this occurs. Instructions to do that:\n\n * `VirtualBox <https://www.virtualbox.org/manual/ch03.html#usb-support>`__\n * `Parallels <https://kb.parallels.com/122993>`__\n * `VMWare Workstation <https://docs.vmware.com/en/VMware-Workstation-Pro/15.0/com.vmware.ws.using.doc/GUID-E003456F-EB94-4B53-9082-293D9617CB5A.html>`__\n\nRebuilding TVM inside the Reference VM\n--------------------------------------\n\nAfter the first boot, you'll need to ensure you keep the build, in ``$TVM_HOME/build-microtvm-zephyr``,\nup-to-date when you modify the C++ runtime or checkout a different revision. You can either\nre-provision the machine (``vagrant provision`` in the same directory you ran ``vagrant up`` before)\nor manually rebuild TVM yourself.\n\nRemember: the TVM ``.so`` built inside the VM is different from the one you may use on your host\nmachine. This is why it's built inside the special directory ``build-microtvm-zephyr``.\n\nLogging in to the VM\n--------------------\n\nThe VM should be available to your host only with the hostname ``microtvm``. You can SSH to the VM\nas follows:\n\n.. code-block:: bash\n\n    $ vagrant ssh\n\nThen ``cd`` to the same path used on your host machine for TVM. For example, on Mac:\n\n.. code-block:: bash\n\n    $ cd /Users/yourusername/path/to/tvm\n\nRunning tests\n=============\n\nOnce the VM has been provisioned, tests can executed using ``poetry``:\n\n.. code-block:: bash\n\n    $ cd apps/microtvm/reference-vm/zephyr\n    $ poetry run python3 ../../../../tests/micro/qemu/test_zephyr.py --zephyr-board=stm32f746g_disco\n\nIf you do not have physical hardware attached, but wish to run the tests using the\nlocal QEMU emulator running within the VM, run the following commands instead:\n\n.. code-block:: bash\n\n    $ cd /Users/yourusername/path/to/tvm\n    $ cd apps/microtvm/reference-vm/zephyr/\n    $ poetry run pytest ../../../../tests/micro/qemu/test_zephyr.py --zephyr-board=qemu_x86\n\n\n\n\n"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.6.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}